const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const Dotenv = require('dotenv-webpack');
const TerserPlugin = require('terser-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const os = require('os');

// 获取本机局域网IP
function getLocalIP() {
  const nets = os.networkInterfaces();
  for (const name of Object.keys(nets)) {
    for (const net of nets[name]) {
      if (net.family === 'IPv4' && !net.internal) {
        return net.address;
      }
    }
  }
  return 'localhost';
}

module.exports = (env = {}, argv = {}) => {
  const isProduction = argv.mode === 'production';

  // 如果有第三方模块需要被 babel 转译（例如某些 ESM 包），在这里填模块名：
  // const transpileModules = ['some-esm-package', 'another-esm-lib'];
  // 或通过环境变量传入： process.env.TRANSPILE_MODULES = 'mod-a,mod-b'
  const transpileModules = process.env.TRANSPILE_MODULES
    ? process.env.TRANSPILE_MODULES.split(',').map((s) => s.trim())
    : [];

  // 生产环境使用 MiniCssExtractPlugin.loader（可以指定 publicPath 修复 windows 路径问题）
  const styleLoader = isProduction
    ? {
        loader: MiniCssExtractPlugin.loader,
        options: {
          // 在某些 Windows/服务器环境下，'' 有更稳定的相对路径处理
          publicPath: '',
        },
      }
    : 'style-loader';

  return {
    mode: isProduction ? 'production' : 'development',
    entry: './src/index.jsx',
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: isProduction ? 'js/[name].[contenthash:8].js' : 'js/[name].js',
      publicPath: '/',
    },

    // 推荐的 devtool：dev/production 分别不同（webpack4）
    devtool: isProduction ? 'source-map' : 'cheap-module-eval-source-map',

    module: {
      rules: [
        {
          test: /\.(js|jsx|mjs)$/,
          // 默认排除 node_modules，但允许对特定模块转译
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true, // 加速重编译（对 Windows 非常友好）
            },
          },
        },

        // 如果需要对 node_modules 中某些模块转译，添加一个单独规则（按需启用）
        ...(transpileModules.length
          ? [
              {
                test: /\.(js|jsx|mjs)$/,
                include: transpileModules.map((mod) =>
                  path.resolve(__dirname, 'node_modules', mod)
                ),
                use: {
                  loader: 'babel-loader',
                  options: { cacheDirectory: true },
                },
              },
            ]
          : []),

        // CSS
        {
          test: /\.css$/,
          exclude: /node_modules/,
          use: [styleLoader, 'css-loader', 'postcss-loader'],
        },
        {
          test: /\.css$/,
          include: /node_modules/,
          use: [styleLoader, 'css-loader'], // 第三方包不走 postcss
        },
        // SCSS/SASS
        {
          test: /\.(scss|sass)$/,
          use: [styleLoader, 'css-loader', 'postcss-loader', 'sass-loader'],
        },

        // 字体文件
        {
          test: /\.(woff2?|eot|ttf|otf)$/,
          use: {
            loader: 'url-loader',
            options: {
              limit: 8192,
              name: 'fonts/[name].[hash:8].[ext]',
            },
          },
        },

        // 图片资源，url-loader + file-loader fallback
        {
          test: /\.(png|jpe?g|gif|svg)$/,
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 8192,
                name: 'images/[name].[hash:8].[ext]',
                fallback: 'file-loader',
              },
            },
          ],
        },
      ],
    },

    resolve: {
      extensions: ['.js', '.jsx', '.json'],
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
    },

    devServer: {
      port: 8080,
      host: '0.0.0.0',
      open: false, // 如果在 Win7 上出现问题，可改为 false
      historyApiFallback: true,
      compress: true,
      onListening: function (devServer) {
        const port = devServer.listeningApp.address().port;
        const ip = getLocalIP(); // 你前面定义的函数
        console.log(`> Dev server running at: http://${ip}:${port}`);
      },
      // 如需在 Win7 上避免 host 检查（开发时）可以启用下面选项（注意安全）
      // disableHostCheck: true,
      proxy: {
        '/api': {
          target: process.env.API_BASE_URL || 'http://localhost:3000',
          changeOrigin: true,
        },
      },
    },

    plugins: [
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
        template: './public/index.html',
        minify: isProduction ? { collapseWhitespace: true, removeComments: true } : false,
      }),
      new Dotenv({
        path: `.env.${argv.mode || 'development'}`,
      }),
      ...(isProduction
        ? [
            new MiniCssExtractPlugin({
              filename: 'css/[name].[contenthash:8].css',
            }),
            // 生产时开启 bundle 分析（可用环境变量控制）
            ...(process.env.ANALYZE ? [new BundleAnalyzerPlugin()] : []),
          ]
        : []),
    ],

    optimization: {
      moduleIds: isProduction ? 'hashed' : 'named',
      splitChunks: {
        chunks: 'all',
        cacheGroups: {
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            chunks: 'all',
          },
        },
      },
      minimizer: isProduction ? [new TerserPlugin({ parallel: true })] : [],
      runtimeChunk: 'single',
    },

    // 在 Windows 下，如果遇到内存/性能问题可以调整下面缓存选项（webpack4 支持 filesystem cache 不完整）
    // cache: { type: 'memory' },
    stats: { children: false },
  };
};
